AWS LambdaでRubyスクリプトをCloudWatchで定期実行する

2019-09-19

AWS Lambda で ruby スクリプトを登録し、CloudWatch で定期的に実行というのを、よく作っているので書いておきます。

今回書いた AWS Lambda で ruby のスクリプト(標準以外の gem を使うパターン)のサンプルはt4traw/lambda-ruby-templateに push しておきました。

まず、実際に書く ruby のコードの注意点として、

  • 関数単位で実行するので、必要な処理は関数にまとめておく
  • その関数の引数にを(event:, context:)としておく
  • gem を使う場合、その gem も zip でまとめてアップロードしないといけないので、ローカルにインストールする(つまりbundle install --path vendor/bundleにしておく必要アリ)

といったところでしょうか。今回は Slack へランダムな文字列を定期的にポストするシンプルなコードを Lambda と CloudWatch で実装したいと思います。

Ruby は一応 2.5.0 をインストールしておく

AWS Lambda の ruby ランタイムは 2.5.0 なので、開発環境も一応 2.5.0 にしておきます。僕の場合は rbenv ですので、こんな具合にしておきます。

$ rbenv install 2.5.0
$ rbenv local 2.5.0

gem をインストールする

ruby2.6 以上だと bundler は標準だったけど、2.5.0 は標準ではないので、まずは bundler をインストールします。で、bundle init します。

$ gem i bundler
$ bundle init

Gemfile に必要な gem を書きます。

# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "slack-notifier"

そしたら、bundle install します。上にもありましたが、あとで gem ごとパッケージしないといけないのでローカルにインストールする必要があります。

$ bundle install --path vendor/bundle

実際にコードを書く

Slack に SecureRandom で生成した文字列を Slack にポストするだけなので、とくに難しいことはありません 😁

Slack の WEBHOOK_URL は各自カスタムインテグレーションで生成してくださいませ。

require 'slack-notifier'
require 'securerandom'

WEBHOOK_URL = 'YOUR_WEBHOOK_URL'

def foobar(event:, context:)
  notifier = Slack::Notifier.new(WEBHOOK_URL)
  notifier.ping SecureRandom.hex(16)
end

試しに、foobar とか書いて、bundle exec ruby app.rbで実行してみてください。

AWS CLI のセットアップ

AWS CLI を使うので、brew でインストールします。

$ brew install awscli

インストールが終わったら、IAM で Lambda, CloudWatch にアクセスができるグループ&ユーザーを作成し、認証を開始します。

途中リージョンを聞かれるので、ap-northeast-1(東京リージョン)を指定しておきます。output format はデフォで構わないので、何も入力せずに Enter を押しておきます。

$ aws configure

デプロイする

Lambda で関数を作成しておきます。

今回作った物を zip でパッケージします。

$ zip -r function.zip app.rb vendor

そして、AWS CLI でデプロイします。—function-name は適宜変更してください。

$ aws lambda update-function-code --function-name 上で作った関数名 --zip-file fileb://function.zip

デプロイできたら Lambda の画面で確認し、イベントハンドラを file_name.function_name に変更し、保存します。

そしたら、試しにスクリプトを lambda 上で実行します。画面上部のテストボタンをおして、パラメーターはとりあえず空の hash で作成し、実行してみます。

無事、動きました 😄

CloudWatch で定期実行する

トリガーを追加をクリックして、CloudWatch Events を追加します。

で、新規ルールの作成をし、ルール名と説明とスケジュールを登録します。スケジュールは cron 式で書けるのですが、日にちか曜日を指定しない場合は?で入力する必要があったりするので、詳しくはドキュメントを参照してください。

ルールのスケジュール式 - Amazon CloudWatch Events

今回は毎週水曜日の日本時間 17 時に実行してほしいので、cron(0 8 ? * WED *)といった感じに書きます。時間は GMT なんで注意してください。

最後に保存(追加ボタンを押す)を忘れないように 👍


以上、簡単な Lambda と CloudWatch の定期実行の方法でした!

一番得意な ruby でサクっと lambda のコードを作れるのが本当に嬉しいですw

また、今までは Heroku Scheduler でなんとかやっていたのですが、Heroku Scheduler は毎分、毎時、毎日のどれかしか選べない……。CloudWatch は cron 式で定期実行でき、他にも CloudWatch で監視している ○○ をフラグに実行など、柔軟な方法を選べるのが最高です!

それでは 👐